#include "queue.h"

void queueInit(Queue *q, int size) {
    q->in = q->out = q->cnt = 0;
    q->size = size;
	q->buf = (char*) malloc(size*sizeof(char));
}

// called from isr, interrupts are disabled,
// can't call C library I/O functions, as they are BIOS based, not reentrant

Bool queuePut(Queue *q, char c) {
	//disable();
	void beep(void);
	
    if (queueFull(q)) {
		beep(); // warning, uses T0 ints!
		//enable();
        return false;
	}
    
    q->buf[q->in++] = c;
    q->in %= q->size;
    q->cnt++;
	//enable();
    return true;
}

// called from C. As it can be interrupted by the isr and manipulates structure fields it is a critical section
int queueGet(Queue *q) {	
	//disable();
    if (queueEmpty(q)) {
		//enable(); // reenable interrupts
        return -1;
	}
    
    char c = q->buf[q->out++];
    q->out %= q->size;
    q->cnt--;
	//enable();
    return c;
}

// should be critical a section
Bool queueEmpty(Queue *q) {
    return q->cnt == 0;
}

// should be critical a section
Bool queueFull(Queue *q) {
    return q->cnt == q->size;
}

void beep() {
	/*
	printf("<beep-start>\n");
	// Programação do Timer_0
	timer_init(0, LCOM_MODE);
	timer_load(0, (int) (TIMER_CLK/1000) );
	
	// Instalação da rotina de atendimento do Timer_0
	_go32_dpmi_seginfo original_vec_c; // Estado de interrupções antigo
	_go32_dpmi_seginfo new_vec_c;
	install_c_irq_handler(T0_IRQ, timer_0_handler, &original_vec_c, &new_vec_c); 
	
	
	// Programação do Timer_2
		// Definir frequencia
		int frequencia = 1318.51;
		int divisor = TIMER_CLK / frequencia;
		
		// Programar timer 2
		timer_init(2,LCOM_MODE); // Programa timer 2
		timer_load(2, (int)divisor ); // Carrega frequencia
		
		// Altifalante on
		outportb(SPEAKER_CTRL, TIMER2_ENABLE | SPEAKER_ENABLE);
		// Espera
		mili_sleep(1000);
		// Altifalante off
		outportb(SPEAKER_CTRL, SPEAKER_DISABLE);
	
	// Repor o handler original
	reinstall_c_irq_handler(T0_IRQ, &original_vec_c, &new_vec_c);
	printf("<beep-end>\n");
	*/
}

